package com.dd.cloud.common.utils;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 拼音工具类
 *
 * @author zk
 */
public class PinYinUtils {

    public static final char[] LETTER = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    /**
     * 中文转拼音 首字母拼音
     *
     * @param str 中文
     * @return
     */
    public static String chineseToPinyinSell(String str) {
        if (str == null || "".equals(str)) {
            return "";
        }
        StringBuilder pinyin = new StringBuilder();
        char[] chars = str.toCharArray();
        /*
         * 输出格式设置
         */
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        /*
         * 输出大小写设置
         * LOWERCASE:输出小写
         * UPPERCASE:输出大写
         */
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        /*
         * 输出音标设置
         * WITH_TONE_MARK:直接用音标符（必须设置WITH_U_UNICODE，否则会抛出异常）
         * WITH_TONE_NUMBER：1-4数字表示音标
         * WITHOUT_TONE：没有音标
         */
        format.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);
        /*
         * 特殊音标ü设置
         * WITH_V：用v表示ü
         * WITH_U_AND_COLON：用"u:"表示ü
         * WITH_U_UNICODE：直接用ü
         */
        format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
        for (char aChar : chars) {
            try {
                if (Character.toString(aChar).matches("[\\u4E00-\\u9FA5]+")) {
                    pinyin.append(PinyinHelper.toHanyuPinyinStringArray(aChar, format)[0].charAt(0));
                } else {
                    pinyin.append(aChar);
                }
            } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                badHanyuPinyinOutputFormatCombination.printStackTrace();
            }
        }
        return pinyin.toString();
    }

    /**
     * 中文转拼音 全拼
     *
     * @param str 中文
     * @return
     */
    public static String chineseToPinyin(String str) {
        if (str == null || str.equals("")) {
            return "";
        }
        StringBuilder pinyin = new StringBuilder();
        char[] chars = str.toCharArray();
        /*
         * 输出格式设置
         */
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        /*
         * 输出大小写设置
         * LOWERCASE:输出小写
         * UPPERCASE:输出大写
         */
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        /*
         * 输出音标设置
         * WITH_TONE_MARK:直接用音标符（必须设置WITH_U_UNICODE，否则会抛出异常）
         * WITH_TONE_NUMBER：1-4数字表示音标
         * WITHOUT_TONE：没有音标
         */
        format.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);
        /*
         * 特殊音标ü设置
         * WITH_V：用v表示ü
         * WITH_U_AND_COLON：用"u:"表示ü
         * WITH_U_UNICODE：直接用ü
         */
        format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
        for (char aChar : chars) {
            try {
                if (Character.toString(aChar).matches("[\\u4E00-\\u9FA5]+")) {
                    pinyin.append(PinyinHelper.toHanyuPinyinStringArray(aChar, format)[0]);
                } else {
                    pinyin.append(aChar);
                }
            } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                badHanyuPinyinOutputFormatCombination.printStackTrace();
            }
        }
        return pinyin.toString();
    }

    static final int MAX = 1 << 30;

    /**
     * 将map转换字母分组map
     *
     * @param map
     * @return
     */
    public static Map<String, List<Object>> pinyinGroupList(Map<String, Object> map) {
        int n = LETTER.length - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        int initialCapacity = (n < 0) ? 1 : (n >= MAX) ? MAX : n + 1;
        float loadFactor = (float) LETTER.length / initialCapacity;
        Map<String, List<Object>> group = new HashMap<>(LETTER.length, loadFactor);
        for (int i = 0; i < LETTER.length; i++) {
            group.put(String.valueOf((char) i), new ArrayList<>());
        }
        //拼音格式
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        //输出大写
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        //不输出音标
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        for (String item : map.keySet()) {
            String letter = null;
            try {
                //转拼音
                letter = String.valueOf(PinyinHelper.toHanyuPinyinStringArray(item.charAt(0), format)[0].charAt(0));
            } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                badHanyuPinyinOutputFormatCombination.printStackTrace();
            }
            if (group.containsKey(letter)) {
                group.get(letter).add(map.get(item));
            } else {
                List<Object> list = new ArrayList<>();
                list.add(map.get(item));
                group.put(letter, list);
            }
        }
        return group;
    }

}
